package com.hnkywl.sts.service.sfgl;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.hnkywl.sts.dao.jhgl.JkdDao;
import com.hnkywl.sts.dao.organ.EjzhDao;
import com.hnkywl.sts.dao.organ.GsjgDao;
import com.hnkywl.sts.dao.sfgl.FkshDao;
import com.hnkywl.sts.dao.sfgl.FkshmxDao;
import com.hnkywl.sts.dao.zjgl.PjglDao;
import com.hnkywl.sts.dao.zjgl.XyzDao;
import com.hnkywl.sts.entity.cggl.Jsd;
import com.hnkywl.sts.entity.htgl.Cght;
import com.hnkywl.sts.entity.jhgl.Jkd;
import com.hnkywl.sts.entity.organ.Ejzh;
import com.hnkywl.sts.entity.organ.Nbgs;
import com.hnkywl.sts.entity.sfgl.Sfk;
import com.hnkywl.sts.entity.sfgl.Sfkmx;
import com.hnkywl.sts.entity.zjgl.Pj;
import com.hnkywl.sts.entity.zjgl.Xyz;
import com.hnkywl.sts.service.base.BmService;
import com.hnkywl.sts.service.base.DxpzService;
import com.hnkywl.sts.service.flow.FlowService;
import com.hnkywl.sts.service.jhgl.JkdService;
import com.hnkywl.sts.service.organ.KhhService;
import com.hnkywl.sts.service.sys.YgService;
import com.hnkywl.sts.service.zjgl.PjglService;
import com.hnkywl.sts.service.zjgl.XyzService;
import com.hnkywl.sts.util.BaseUtils;
import com.hnkywl.sts.util.ReflectionUtils;
import net.ruixin.orm.hibernate.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 说明：
 * 包:        com.hnkywl.sts.service.sfgl
 * 类描述:   付款审核服务类
 * 修改备注: [说明本次修改内容]
 * 版本:        [v1.0]
 */
@Service
public class FkshService {
    private BmService bmService;
    private FkshDao fkshDao;
    private KhhService khhService;
    private PjglService pjglService;
    private XyzService xyzService;
    private JkdDao jkdDao;
    private FkshmxDao fkshmxDao;
    private JkdService jkdService;
    private GsjgDao gsjgDao;
    private FlowService flowService;
    private PjglDao pjglDao;
    private XyzDao xyzDao;
    private EjzhDao ejzhDao;
    private DxpzService dxpzService;


    /**
     * 查询付款审核列表
     *
     * @param sbgsMc
     * @param sbgsId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Transactional
    public String findAllFksh(Date fkshStart, Date fkshEnd, String bm, String sbgsMc, Long sbgsId, String gldwMc, String zt, String fklx, String zdr,int pageNo, int pageSize) {
        Long nbgsIds = null;
        if (sbgsId != null && sbgsMc.equals(gsjgDao.get(sbgsId).getJc())) {
            nbgsIds = sbgsId;
        }
        Page<Sfk> sfkPage = this.fkshDao.findFklxList(fkshStart, fkshEnd, bm, sbgsMc, nbgsIds, gldwMc, zt, fklx,zdr, pageNo, pageSize);
        List<Sfk> sfkList = sfkPage.getResult() == null ? new ArrayList<Sfk>() : sfkPage.getResult();
        String sfkJson = BaseUtils.fetchCollectionToJson(sfkList, "id", "bm", "sfkrq", "sfklx", "gldw.qc", "pjlx.z", "sfje", "kxlx", "shrq", "sbgs.jc", "sbr.xm", "bz", "zt", "qtfk", "processInstanceId", "createUser.id", "createUser.xm");
        return "{\"total\":" + sfkPage.getTotalCount() + ",\"rows\":[" + sfkJson + "]}";
    }

    @Transactional
    public String findAllDbsfrw(Long gsId) {
        List<Map> sfkList = this.fkshDao.findAllDbsfrw(gsId);
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
        String json = gson.toJson(sfkList);
        return "{\"rows\":" + json + "}";
    }


    @Transactional
    public String findfkshByCghtList(Long cghtId, int pageNo, int pageSize) {
        List<Jkd> jkds = this.jkdService.findJkdDetailByCght(cghtId);
        List<Sfk> sfkList = new ArrayList<Sfk>();
        Integer count = 0;
        if (jkds.size() > 0) {
            for (Jkd jkd : jkds) {
                List<Sfkmx> sfkmxLst = jkd.getSfkmxList();
                if (sfkmxLst != null) {
                    for (Sfkmx sfkmx : sfkmxLst) {
                        if (sfkmx.getFksh() != null) {
                            Page<Sfk> sfkPage = this.fkshDao.findfkshBySfkList(sfkmx.getFksh().getId(), pageNo, pageSize);
                            sfkList.addAll(sfkPage.getResult());
                            count += sfkPage.getTotalCount();
                        }
                    }
                }
            }
        }

        String sfkJson = BaseUtils.fetchCollectionToJson(sfkList, "id", "bm", "sfkrq", "sfklx", "gldw.jc", "pjlx.z", "sfje", "sbgs.jc", "sbr.xm", "bz", "zt", "createUser.id", "createUser.xm");
        return "{\"total\":" + count + ",\"rows\":[" + sfkJson + "]}";
    }

    /**
     * 首页显示付款单数
     *
     * @return
     */
    public String findAllFksh() {
        return this.fkshDao.findAllfksh();
    }

    public Boolean checkAddFkshJe(Sfk fksh) {
        for (Sfkmx sfkmx : fksh.getSfkmxList()) {
            List<Sfkmx> sfkmxList = fkshmxDao.findBySfkmxByJkdId(sfkmx.getJkd().getId());
            Double yfje = 0.0;
            if (sfkmxList.size() > 0) {
                for (Sfkmx s : sfkmxList) {
                    yfje += Double.parseDouble(s.getBcfkmx().toString());
                }
            }
            if (Double.parseDouble(sfkmx.getBcfkmx().toString()) + yfje > Double.parseDouble(sfkmx.getJkd().getZfje().toString())) {
                return false;
            }
        }
        return true;
    }

    /**
     * 保存付款审核信息
     *
     * @param sfk 付款审核实体
     * @return
     */
    @Transactional
    public void saveFksh(Sfk sfk) {
        nullId(sfk);
        sfk.setDateCreated(new Date());
        if(sfk.getBz() != null){
            Pattern p = Pattern.compile("\t|\r|\n");
            Matcher m = p.matcher(sfk.getBz());
            String bz = m.replaceAll("");
            sfk.setBz(bz);
        }
        sfk.setWlzlx(0);
        sfk.setCreateUser(YgService.getCurrentYg());
        sfk.setCreateOrgan(YgService.getCurrentYg().getZggs());
        sfk.setCreateDepartment(YgService.getCurrentYg().getZgjg());
        sfk.setLastUpdated(sfk.getDateCreated());
        sfk.setBm(this.bmService.getSfdbm("FK"));
        sfk.setSfwsyfk(0);
        sfk.setZt("ybc");
        sfk.setQtfk(0);
        this.fkshDao.save(sfk);
        Double yfje = 0d;
        for (Sfkmx fkshmx : sfk.getSfkmxList()) {
            Sfkmx n = new Sfkmx();
            n.setFkrq(new Date());
            n.setFksh(sfk);
            n.setBcfkmx(Double.parseDouble(fkshmx.getBcfkmx().toString()));
            n.setDateCreated(new Date());
            n.setLastUpdated(n.getDateCreated());
            n.setCreateUser(YgService.getCurrentYg());
            n.setCreateOrgan(YgService.getCurrentYg().getZggs());
            n.setCreateDepartment(YgService.getCurrentYg().getZgjg());
            Jkd j = jkdDao.get(fkshmx.getJkd().getId());
            yfje = Double.parseDouble(fkshmx.getJkd().getYfje().toString()) + Double.parseDouble(fkshmx.getBcfkmx().toString());
            j.setYfje(yfje);
            jkdDao.save(j);
            n.setJkd(j);
            fkshmxDao.save(n);
        }
    }

    @Transactional
    public void saveTkFksh(Sfk sfk, String sfje) {
        nullId(sfk);
        sfk.setSfje(Double.parseDouble(sfje.replace(",", "").replace("，", "")));
        if(sfk.getBz() != null){
            Pattern p = Pattern.compile("\t|\r|\n");
            Matcher m = p.matcher(sfk.getBz());
            String bz = m.replaceAll("");
            sfk.setBz(bz);
        }
        sfk.setWlzlx(0);
        sfk.setCreateUser(YgService.getCurrentYg());
        sfk.setCreateOrgan(YgService.getCurrentYg().getZggs());
        sfk.setCreateDepartment(YgService.getCurrentYg().getZgjg());
        sfk.setDateCreated(new Date());
//        sfk.setSfkrq(sfk.getDateCreated());
        sfk.setLastUpdated(sfk.getDateCreated());
        sfk.setSftpfy("ftpfk");
        sfk.setBm(this.bmService.getSfdbm("FK"));
        sfk.setZt("ybc");
        sfk.setSfwsyfk(0);
        sfk.setQtfk(1);
        this.fkshDao.save(sfk);
    }


    @Transactional
    public void saveBgFksh(Sfk bgsk) {
        nullId(bgsk);
        bgsk.setCreateUser(YgService.getCurrentYg());
        bgsk.setCreateOrgan(YgService.getCurrentYg().getZggs());
        bgsk.setCreateDepartment(YgService.getCurrentYg().getZgjg());
        bgsk.setSfkrq(bgsk.getDateCreated());
        bgsk.setLastUpdated(bgsk.getDateCreated());
        bgsk.setBm(this.bmService.getSfdbm("FK"));
        bgsk.setZt("ybc");
        bgsk.setSfwsyfk(1);
        this.fkshDao.save(bgsk);
    }

    /**
     * 更新付款审核信息
     *
     * @param sfk 付款审核实体
     * @return
     */
    @Transactional
    public void updateFksh(Sfk sfk) {
        Sfk clone = this.findFkshDetail(sfk.getId());
        Integer wsy = clone.getSfwsyfk();
        nullId(sfk);
        clone = (Sfk) ReflectionUtils.getInstance(clone, sfk);
        clone.setLastUpdated(new Date());
        clone.setSfkrq(sfk.getSfkrq());
        clone.setSfwsyfk(wsy);
        this.fkshDao.save(clone);
        List<Sfkmx> sfkmxList = fkshmxDao.findBySfkmxId(sfk.getId());
        Map<Long, Double> temp = new HashMap<Long, Double>();
        for (Sfkmx t : sfkmxList) {//因为有删除按钮将所有的原收付款关联的收付款明细删除
            fkshmxDao.delete(t);
            temp.put(t.getJkd().getId(), Double.parseDouble(t.getBcfkmx().toString()));
        }
        for (Sfkmx fkshmx : sfk.getSfkmxList()) {
            Sfkmx n = new Sfkmx();
            n.setFkrq(new Date());
            n.setFksh(sfk);
            n.setBcfkmx(Double.parseDouble(fkshmx.getBcfkmx().toString()));
            n.setDateCreated(new Date());
            n.setLastUpdated(n.getDateCreated());
            Jkd j = jkdDao.get(fkshmx.getJkd().getId());
            if (!j.getVersion().equals(fkshmx.getJkd().getVersion())) {
                throw new RuntimeException("借款单正在操作，请刷新重试");
            }
            Double yfje;
            if (temp.containsKey(j.getId())) {
                yfje = Double.parseDouble(fkshmx.getJkd().getYfje().toString()) + Double.parseDouble(fkshmx.getBcfkmx().toString()) - temp.get(j.getId());
            } else {
                yfje = Double.parseDouble(fkshmx.getJkd().getYfje().toString()) + Double.parseDouble(fkshmx.getBcfkmx().toString());
            }
            j.setYfje(yfje);
            jkdDao.save(j);
            n.setJkd(j);
            fkshmxDao.save(n);
        }

        if (sfk.getZt().equals("yrz") || sfk.getZt().equals("yth")) {
                List<Pj> rzpjList = pjglDao.getPjByFkId(sfk.getId());
                if (rzpjList.size() > 0) {
                    for (Pj pj : rzpjList) {
                        if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                            throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                        }
                        pj.setStatus(1);
                        pj.setLastUpdated(new Date());
                        pjglService.savePjgl(pj);
                    }
                    sfk.setPjList(null);
                }
                //删掉背书的票据
                List<Pj> bspjList = pjglDao.getPjBySkId(sfk.getId());
                if (bspjList.size() > 0) {
                    for (Pj pj : bspjList) {
                        if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                            throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                        }
                        pj.setStatus(1);
                        pj.setLastUpdated(new Date());
                        pjglService.savePjgl(pj);
                    }
                    sfk.setPjList(null);
                }
                List<Xyz> rzxyzList = xyzDao.getXyzBySFKId(sfk.getId());
                if (rzxyzList.size() > 0) {
                    for (Xyz xyz : rzxyzList) {
                        if (xyz.getStatus() == 3) {
                            throw new RuntimeException("信用证已变现，请先取消还款");
                        }
                        xyz.setLastUpdated(new Date());
                        xyz.setStatus(1);
                        xyzService.saveOldXyz(xyz);
                    }
                }
            this.saveFksh(sfk);
        }
    }

    @Transactional
    public void updateTKFksh(Sfk sfk, String sfje) {
        Sfk clone = this.findFkshDetail(sfk.getId());
        Integer wsy = clone.getSfwsyfk();
        nullId(sfk);
        clone = (Sfk) ReflectionUtils.getInstance(clone, sfk);
        clone.setLastUpdated(new Date());
        clone.setSfkrq(sfk.getSfkrq());
        clone.setSfwsyfk(wsy);
        clone.setSfje(Double.parseDouble(sfje.replace(",", "").replace("，", "")));
        clone.setSftpfy("ftpfk");
        List<Pj> rzpjList = pjglDao.getPjByFkId(sfk.getId());
        if (rzpjList.size() > 0) {
            for (Pj pj : rzpjList) {
                if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                    throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                }
                pj.setStatus(1);
                pj.setLastUpdated(new Date());
                pjglService.savePjgl(pj);
            }
            sfk.setPjList(null);
        }
        //删掉背书的票据
        List<Pj> bspjList = pjglDao.getPjBySkId(sfk.getId());
        if (bspjList.size() > 0) {
            for (Pj pj : bspjList) {
                if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                    throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                }
                pj.setStatus(1);
                pj.setLastUpdated(new Date());
                pjglService.savePjgl(pj);
            }
            sfk.setPjList(null);
        }
        List<Xyz> rzxyzList = xyzDao.getXyzBySFKId(sfk.getId());
        if (rzxyzList.size() > 0) {
            for (Xyz xyz : rzxyzList) {
                if (xyz.getStatus() == 3) {
                    throw new RuntimeException("信用证已变现，请先取消还款");
                }
                xyz.setLastUpdated(new Date());
                xyz.setStatus(1);
                xyzService.saveOldXyz(xyz);
            }
        }
        this.fkshDao.save(clone);
    }


    /**
     * 更新付款审核信息
     *
     * @param sfk 付款审核实体
     * @return
     */
    @Transactional
    public void updateBgFksh(Sfk sfk) {
        Sfk clone = this.findFkshDetail(sfk.getId());
        Integer wsy = clone.getSfwsyfk();
        nullId(sfk);
        clone.setDateCreated(sfk.getDateCreated());
        clone = (Sfk) ReflectionUtils.getInstance(clone, sfk);
        clone.setLastUpdated(new Date());
        clone.setSfkrq(clone.getDateCreated());
        clone.setSfwsyfk(wsy);
        this.fkshDao.save(clone);
    }

    /**
     * 删除付款审核信息
     *
     * @param id 付款审核id
     * @return
     */
    @Transactional
    public void deleteFksh(Long id) {
        Sfk sfk = fkshDao.get(id);
        sfk.setLastUpdated(new Date());
        sfk.setDeleted(1);

        List<Sfkmx> sfkmxList = fkshmxDao.findBySfkmxId(sfk.getId());
        if (sfkmxList != null) {
            for (Sfkmx temp : sfkmxList) {
                Sfkmx x = fkshmxDao.get(temp.getId());
//                x.setFksh(sfk);
                Jkd j = jkdDao.get(temp.getJkd().getId());
                Double yfje = Double.parseDouble(x.getJkd().getYfje().toString()) - Double.parseDouble(x.getBcfkmx().toString());
                j.setYfje(yfje);
                jkdService.saveJkdSyzt(j);
                x.setBcfkmx(Double.parseDouble(temp.getBcfkmx().toString()));
                x.setLastUpdated(new Date());
                fkshmxDao.save(x);
            }
            for (Sfkmx t : sfkmxList) {
                t.setDeleted(1);
                t.setLastUpdated(new Date());
                fkshmxDao.save(t);
            }
        }
        if (sfk.getZt().equals("yrz") || sfk.getZt().equals("yth")) {
            List<Pj> rzpjList = pjglDao.getPjByFkId(sfk.getId());
            if (rzpjList.size() > 0) {
                for (Pj pj : rzpjList) {
                    if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                        throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                    }
                    pj.setStatus(1);
                    pj.setLastUpdated(new Date());
                    pjglService.savePjgl(pj);
                }
                sfk.setPjList(null);
            }
            //删掉背书的票据
            List<Pj> bspjList = pjglDao.getPjBySkId(sfk.getId());
            if (bspjList.size() > 0) {
                for (Pj pj : bspjList) {
                    if (pj.getStatus() == 2 || pj.getStatus() == 3 || pj.getStatus() == 4) {
                        throw new RuntimeException("票据已贴现托收或承兑，请先退回!");
                    }
                    pj.setStatus(1);
                    pj.setLastUpdated(new Date());
                    pjglService.savePjgl(pj);
                }
                sfk.setPjList(null);
            }
            List<Xyz> rzxyzList = xyzDao.getXyzBySFKId(sfk.getId());
            if (rzxyzList.size() > 0) {
                for (Xyz xyz : rzxyzList) {
                    if (xyz.getStatus() == 3) {
                        throw new RuntimeException("信用证已变现，请先取消还款");
                    }
                    xyz.setLastUpdated(new Date());
                    xyz.setStatus(1);
                    xyzService.saveOldXyz(xyz);
                }
                sfk.setXyzList(null);
            }
        }
        this.fkshDao.save(sfk);
    }

    /**
     * 查询收付款明细
     *
     * @param processInstanceId 收付款ID
     * @return
     */
    @Transactional
    public Sfk findSfkDetailByProcessInstance(String processInstanceId) {
        return this.fkshDao.findUniqueByProperty("processInstanceId", processInstanceId);
    }


    /**
     * 查询付款审核明细
     *
     * @param id
     * @return
     */
    @Transactional
    public Sfk findFkshDetail(Long id) {
        return this.fkshDao.getFksh(id);
    }

    /**
     * 修改付款审核时间
     *
     * @param
     * @return
     */
    @Transactional
    public void xgshrq(Sfk fksh) {
        Sfk sfk = this.findFkshDetail(fksh.getId());
        sfk.setShrq(fksh.getShrq());
        this.fkshDao.save(sfk);
    }


    /**
     * 付款审核操作流程
     *
     * @param fkshId
     * @return
     */
    @Transactional
    public void checkFkshPj(Long fkshId, String pjIds) {
        Sfk sfk = this.findFkshDetail(fkshId);
        List<Pj> rzpjList = pjglDao.getPjByFkId(sfk.getId());
        for (Pj p : rzpjList) {
            p.setStatus(1);
            pjglDao.save(p);
        }
        sfk.setLastUpdated(new Date());
        sfk.setZt("yrz");
        this.fkshDao.save(sfk);
        String[] pjs = pjIds.split(",");
        Double pjzje = 0.0;
        for (String id : pjs) {
            Pj pj = pjglService.findPjDetail(Long.parseLong(id));
            pjzje += Double.parseDouble(pj.getDqje().toString());
        }
        if((pjzje*100)/100 != sfk.getSfje()){
            throw new RuntimeException("票据总金额必须等于收付款金额");
        }
        for (String id : pjs) {
            Pj pj = pjglService.findPjDetail(Long.parseLong(id));
            pj.setSpr(sfk.getGldw());
            pj.setStatus(5);
            pj.setSyrq(new Date());
            if (sfk.getSfklx() == 1 || sfk.getSfklx() == 2) {
                pj.setSfk(sfk);
            } else {
                pj.setSk(sfk);
            }
            pjglService.savePjgl(pj);
        }
    }

    /**
     * 审核信用证
     *
     * @param fkshId
     * @param xyzIds
     */
    @Transactional
    public void checkFkshXyz(Long fkshId, String xyzIds) {
        Sfk sfk = this.findFkshDetail(fkshId);
        sfk.setLastUpdated(new Date());
        sfk.setZt("yrz");
        this.fkshDao.save(sfk);
        String[] xyzs = xyzIds.split(",");
        for (String id : xyzs) {
            Xyz xyz = this.xyzService.findXyzDetail(Long.parseLong(id));
            xyz.setJzdw(sfk.getGldw());
            xyz.setStatus(4);
            xyz.setLastUpdated(new Date());
            xyz.setSyrq(new Date());
            xyz.setSfk(sfk);
            xyz.setSfdrlx("wdr");
            this.xyzService.saveOldXyz(xyz);
        }
    }


    /**
     * 付款审核操作流程
     *
     * @param fkshId
     * @return
     */
    @Transactional
    public void checkFksh(Long fkshId, Long nbkhhId,Long glkhhId) {
        Sfk sfk = this.findFkshDetail(fkshId);
        if(glkhhId != null){
            sfk.setGlkhh(khhService.findKhhById(glkhhId));
        }
        sfk.setNbkhh(khhService.findKhhById(nbkhhId));
        nullId(sfk);
        sfk.setLastUpdated(new Date());
        sfk.setZt("yrz");
        this.fkshDao.save(sfk);
    }

    /**
     * ajax远程验证
     *
     * @param value 验证值
     * @param field 验证字段
     * @return
     */
    public boolean ajaxValidate(Long id, String value, Object field) {
        return fkshDao.checkUnique(id, value, field);
    }

    @Transactional
    public void changeStatus(String ids, String status) {
        String[] fkIds = ids.split(",");
        for (String id : fkIds) {
            Sfk sfk = this.findFkshDetail(Long.parseLong(id));
            sfk.setZt(status);
            sfk.setShrq(new Date());
            sfk.setShr(YgService.getCurrentYg());
            this.fkshDao.save(sfk);
        }
    }



    @Transactional
    public void changeStatusNbhz(String ids, String status) {
        String[] fkIds = ids.split(",");
        List<Sfk> sfkList  = new ArrayList<Sfk>();
        //1.取到所有的收付款
        for (String id : fkIds) {
            Sfk sfk = this.findFkshDetail(Long.parseLong(id));
            sfkList.add(sfk);
        }
        //2.判断所有的收付款的创建公司还有关联公司都需要是内部公司
        if(!checkSfkNbgsAndGldw(sfkList)){
            throw new RuntimeException("收付款的关联单位不是内部公司，不可进行内部划转");
        }
        //3划转一条收付款
        for (Sfk sfk :sfkList){
           if(!sfk.getPjlx().getZ().equals("银票")
                     && !sfk.getPjlx().getZ().equals("商票") &&
                             !sfk.getPjlx().getZ().equals("信用证")){//收付款为现汇的
              if(checkSfkRzyh(sfk).get("flag").equals("0")){//入账银行关联银行必须全部填写
                 throw new RuntimeException((String)checkSfkRzyh(sfk).get("message"));
              }
              this.ZdhzSfkByXh(sfk,"ysh");//现汇的自动划转

           } else if(sfk.getPjlx().getZ().equals("银票")
                         || sfk.getPjlx().getZ().equals("商票")){//收付款为票据的
               ZdhzSfkByPj(sfk,"ysh");

            }else if(sfk.getPjlx().getZ().equals("信用证")) {//收付款为信用证的
               ZdhzSfkByXYZ(sfk,"ysh");
           }
        }
    }

    /**
     * 处理收付款通用方法
     * @param sfk
     * @param status
     * @return
     */
    protected void checkSfkpublicMethod(Sfk sfk,String status){
        sfk.setZt(status);
        sfk.setShrq(new Date());
        sfk.setShr(YgService.getCurrentYg());
        this.fkshDao.save(sfk);
    }

    /**
     * 检查收付款的创建公司还有关联单位是不是都是背部单位
     * @param sfkList
     * @return
     */
    private Boolean checkSfkNbgsAndGldw(List<Sfk> sfkList){
        for(Sfk sfk :sfkList){
            if(! sfk.getSbgs().className().equals("Nbgs") ||   !sfk.getSbgs().className().equals("Nbgs")){
                return false;
            }
        }
        return true;
    }

    /**
     * 检查收付款的入账银行
     * @param sfk
     * @return
     */
    private  Map<String,Object>  checkSfkRzyh(Sfk sfk){
        Map<String,Object> response = new HashMap<String, Object>();
        if(sfk.getNbkhh() == null ){
            response.put("flag","0");
            response.put("message","收付款"+sfk.getBm()+"的内部开户行不可为空");
        }else if(sfk.getGlkhh() == null ){
            response.put("flag","0");
            response.put("message","收付款"+sfk.getBm()+"的关联开户行不可为空");
        }else{
            response.put("flag","1");
            response.put("message","");
        }
        return response;
    }

    /**
     * 自动划转现汇收付款
     * @param sfk
     */
    private void ZdhzSfkByXh(Sfk sfk,String status){
        //1。先处理付款
        this.checkSfkpublicMethod(sfk,status);
        //2.生成收款
        Sfk sk = new Sfk();
        sk.setDateCreated(new Date());
        sk.setSfje(Double.parseDouble(sfk.getSfje().toString().replace(",", "").replace("，", "")));
        sk.setLastUpdated(sfk.getDateCreated());
        sk.setCreateUser(null);
        sk.setCreateOrgan(sfk.getGldw());
        sk.setCreateDepartment(null);
        sk.setBm(this.bmService.getSfdbm("SK"));
        if(sfk.getSfklx()==1){
            sk.setSfklx(3);
        }else{
            sk.setSfklx(4);
        }
        sk.setPjlx(sfk.getPjlx());
        sk.setKxyt(sfk.getKxyt());
        sk.setKxlx(sfk.getKxlx());
        sk.setSfkrq(sfk.getSfkrq());
        //将收款的关联开户行还有内部开户行调转
        sk.setGlkhh(sfk.getNbkhh());
        sk.setNbkhh(sfk.getGlkhh());
        //将收款的申报公司还有关联单位调换
        sk.setGldw(sfk.getSbgs());
        sk.setSbgs((Nbgs)sfk.getGldw());
        //保存收款
        this.fkshDao.save(sk);
        //关联付款还有收款的自动划转关系保存
        sfk.setNbhzsfk(sk);
        sfk.setZdhz(1);
        sk.setZdhz(1);
        sk.setZt("ytj");
        this.fkshDao.save(sfk);
    }


    /**
     * 自动划转票据类型的收付款
     * @param sfk
     */
    private void ZdhzSfkByPj(Sfk sfk,String status){
        //1。先处理付款
        this.checkSfkpublicMethod(sfk,status);
        //2.生成收款
        Sfk sk = new Sfk();
        sk.setDateCreated(new Date());
        sk.setSfje(Double.parseDouble(sfk.getSfje().toString().replace(",", "").replace("，", "")));
        sk.setLastUpdated(sfk.getDateCreated());
        sk.setCreateUser(null);
        sk.setCreateOrgan(sfk.getGldw());
        sk.setCreateDepartment(null);
        sk.setBm(this.bmService.getSfdbm("SK"));
        sk.setGldw(sfk.getSbgs());
        sk.setSbgs((Nbgs)sfk.getGldw());
        if(sfk.getSfklx()==1){
            sk.setSfklx(3);
        }else{
            sk.setSfklx(4);
        }
        sk.setPjlx(sfk.getPjlx());
        sk.setKxyt(sfk.getKxyt());
        sk.setKxlx(sfk.getKxlx());
        sk.setSfkrq(sfk.getSfkrq());
      //找到付款关联的票据 1应收票据（背书） 2 应付票据
        //关联票据
        List<Pj> rzpjList = pjglDao.getPjByFkOrSkId(sfk.getId());
        for(Pj p :rzpjList){
            if(p.getPjsflx()==0){//应收票据  背书
                //1背书 根据应收票据生成一个应收票据 创建公司修改一下
                Pj hzpj = new Pj();
                hzpj.setNbgs((Nbgs) sfk.getGldw());
                hzpj.setPjsflx(0);
                hzpj.setPjlx(p.getPjlx());
                hzpj.setCprq(p.getCprq());
                hzpj.setPjhm(p.getPjhm());
                hzpj.setKhzt(0);
                hzpj.setDqr(p.getDqr());
                hzpj.setDqje(Double.parseDouble(p.getDqje().toString()));
                hzpj.setJpdw(p.getJpdw());
                hzpj.setJprq(p.getJprq());
                hzpj.setDateCreated(new Date());
                hzpj.setCreateUser(null);
                hzpj.setCreateOrgan(sfk.getGldw());
                hzpj.setCreateDepartment(null);
                hzpj.setLastUpdated(hzpj.getDateCreated());
                hzpj.setSyrq(p.getSyrq());
                hzpj.setCpr(p.getCpr());
                hzpj.setSkr(p.getSkr());
                hzpj.setYscpyh(p.getYscpyh());
                hzpj.setSfk(sfk);
                hzpj.setSk(sk);
                hzpj.setStatus(1);
                hzpj.setNbhzpj(p);
                this.pjglDao.save(hzpj);
            }else{
                //2非背书 根据应付票据生成应收票据
                Pj hzpj = new Pj();
                hzpj.setCprq(p.getCprq());
                hzpj.setYscpyh(p.getYfcpyh().getQc());
                hzpj.setCpr(sfk.getSbgs().getQc());
                hzpj.setSkr(sfk.getGldw().getQc());
                hzpj.setDqje(Double.parseDouble(p.getDqje().toString()));
                hzpj.setDqr(p.getDqr());
                hzpj.setBz("todo");
                hzpj.setPjhm(p.getPjhm());
                hzpj.setPjlx(p.getPjlx());
                hzpj.setNbgs((Nbgs) sfk.getGldw());
                hzpj.setJpdw(sfk.getSbgs());
                hzpj.setLastUpdated(new Date());
                hzpj.setKhzt(0);
                hzpj.setDateCreated(new Date());
                hzpj.setCreateUser(null);
                hzpj.setCreateOrgan(sfk.getGldw());
                hzpj.setCreateDepartment(null);
                hzpj.setLastUpdated(hzpj.getDateCreated());
                hzpj.setPjsflx(0);
                hzpj.setStatus(1);
                hzpj.setSfk(sfk);
                hzpj.setSk(sk);
                hzpj.setNbhzpj(p);
                this.pjglDao.save(hzpj);
            }
        }
        //todo
        //保存收款
        sk.setZdhz(1);
        sk.setZt("ytj");
        this.fkshDao.save(sk);
        //关联付款还有收款的自动划转关系保存
        sfk.setNbhzsfk(sk);
        sfk.setZdhz(1);
        this.fkshDao.save(sfk);
    }

    /**
     * 自动划转信用证类型的收付款
     * @param sfk
     */
    private void ZdhzSfkByXYZ(Sfk sfk,String status){
        //1。先处理付款
        this.checkSfkpublicMethod(sfk,status);
        //2.生成收款
        Sfk sk = new Sfk();
        sk.setDateCreated(new Date());
        sk.setSfje(Double.parseDouble(sfk.getSfje().toString().replace(",", "").replace("，", "")));
        sk.setLastUpdated(sfk.getDateCreated());
        sk.setCreateUser(null);
        sk.setCreateOrgan(sfk.getGldw());
        sk.setCreateDepartment(null);
        sk.setBm(this.bmService.getSfdbm("SK"));
        sk.setGldw(sfk.getSbgs());
        sk.setSbgs((Nbgs)sfk.getGldw());
        if(sfk.getSfklx()==1){
            sk.setSfklx(3);
        }else{
            sk.setSfklx(4);
        }
        sk.setPjlx(sfk.getPjlx());
        sk.setKxyt(sfk.getKxyt());
        sk.setKxlx(sfk.getKxlx());
        sk.setSfkrq(sfk.getSfkrq());
        //关联信用证
        List<Xyz> rzxyzList = xyzDao.getXyzBySFKId(sfk.getId());
       for(Xyz xyz :rzxyzList){
           Xyz z = new Xyz();
           z.setCzrq(new Date());
           z.setYsczyh(xyz.getYfczyh().getQc());
           z.setCzr(sfk.getSbgs().getQc());
           z.setSkr(sfk.getGldw().getQc());
           z.setXyzhm(xyz.getXyzhm());
           z.setKzf(xyz.getKzf());
           z.setDqje(Double.parseDouble(xyz.getDqje().toString()));
           z.setYll(xyz.getYll());
           z.setLxe(xyz.getLxe());
           z.setJkrq(xyz.getJkrq());
           z.setDqrq(xyz.getDqrq());
           z.setSfwffx(xyz.getSfwffx());
           z.setNbgs((Nbgs) sfk.getGldw());
           z.setXyzsflx(0);
           z.setSfk(sk);
           z.setStatus(1);
           z.setLastUpdated(new Date());
           z.setCreateUser(null);
           z.setCreateOrgan(sfk.getGldw());
           z.setCreateDepartment(null);
           z.setNbhzxyz(xyz);
           this.xyzDao.save(z);
       }
        //todo
        //保存收款
        sk.setZdhz(1);
        sk.setZt("ytj");
        this.fkshDao.save(sk);
        //关联付款还有收款的自动划转关系保存
        sfk.setNbhzsfk(sk);
        sfk.setZdhz(1);
        this.fkshDao.save(sfk);
    }


    @Transactional
    public void FkshTj(String ids, String status) {
        String[] fkIds = ids.split(",");
        for (String id : fkIds) {
            Sfk sfk = this.findFkshDetail(Long.parseLong(id));
            Ejzh ejzh = sfk.getDfejzh();
            if(sfk.getKxyt().getZ().equals("提现")) {
                if (ejzh.getKyye() < sfk.getSfje()) {
                    throw new RuntimeException("二级账户" + ejzh.getQc() + "可用余额不足");
                }
                ejzh.setKyye((ejzh.getKyye() == null ? 0 : ejzh.getKyye()) - sfk.getSfje());
                ejzh.setYe((ejzh.getYe() == null ? 0 : ejzh.getYe()) - sfk.getSfje());
                ejzhDao.save(ejzh);
             }
//            }else{
//                tjFkshEjzhhz(sfk);
//            }

            if (this.flowService.checkFlowStart("付款流程")) {
                String processInstanceId = this.flowService.regTask(sfk.getProcessInstanceId(), "付款流程", StringUtils.EMPTY);
                sfk.setProcessInstanceId(processInstanceId);
                sfk.setZt("ytj");
            } else {
                sfk.setZt("ysh");
                sfk.setShrq(new Date());
            }
            sfk.setLastUpdated(new Date());
            this.fkshDao.save(sfk);
            //短信提醒
            if(sfk.getKxyt().getZ().equals("提现") && sfk.getZt().equalsIgnoreCase("ysh")) {
                dxpzService.sendSMS("XJJYTX",ejzh.getKh().getLxsj(),ejzh.getKh().getJc(),new SimpleDateFormat("yyyy年MM月dd日").format(new Date()),
                        "提现",String.format("%.2f",sfk.getSfje()),String.format("%.2f",ejzh.getYe()));
            }
        }
    }

    /**
     * 提交付款审核二级账户划转
     * @param
     * @param
     */
    @Transactional
    public void tjFkshEjzhhz(Sfk sfk) {
        Ejzh e = ejzhDao.findKyyeByKhId(sfk.getSbgs().getId(),sfk.getSbgs().getId());
        if(!sfk.getPjlx().getZ().equals("银票") && !sfk.getPjlx().getZ().equals("商票")) {
            if (e.getKhh().getId() == sfk.getNbkhh().getId()) {
                //1.二级账户可用余额>付款金额
                if (e.getKyye() > sfk.getSfje() && e.getYe() > sfk.getSfje()) {
                    e.setKyye(e.getKyye() - sfk.getSfje());
                    e.setYe(e.getYe() - sfk.getSfje());
                    e.setLastUpdated(new Date());
                    sfk.setDfejzh(e);
                    fkshDao.save(sfk);
                    ejzhDao.save(e);
                }
                if (e.getKyye() < sfk.getSfje()) {
                    throw new RuntimeException("二级账户" + e.getQc() + "可用余额不足");
                }
                if (e.getYe() < sfk.getSfje()) {
                    throw new RuntimeException("二级账户" + e.getQc() + "余额不足");
                }
            }
        }
    }


    @Transactional
    public void FkshQxsh(Long id, String status) {
        Sfk sfk = this.findFkshDetail(id);
        if((sfk.getSfklx()==1 || sfk.getSfklx()==2 )&& sfk.getZdhz()==1){ //付款
              if(sfk.getNbhzsfk() != null && sfk.getNbhzsfk().getZt().equals("ysh")){
                  throw  new RuntimeException("付款生成的自动划转收款"+sfk.getNbhzsfk().getBm()+"已经审核，请取消审核收款");
              }
            if(sfk.getNbhzsfk() != null && sfk.getNbhzsfk().getZt().equals("ytj")){//删除收款
                Sfk nbhzsk = sfk.getNbhzsfk();
                nbhzsk.setDeleted(1);
                this.fkshDao.save(nbhzsk);
                List<Pj> rzpj  = pjglDao.getPjBySkId(nbhzsk.getId());
                if(rzpj.size()>0){
                    for(Pj p :rzpj){
                        p.setDeleted(1);
                        p.setLastUpdated(new Date());
                        pjglDao.save(p);
                    }
                }
            }
        }
        sfk.setZt(status);
        sfk.setLastUpdated(new Date());
        if(sfk.getKxyt().getZ().equals("提现")){
            Ejzh ejzh = sfk.getJfejzh();
            ejzh.setKyye((ejzh.getKyye()==null?0:ejzh.getKyye())+sfk.getSfje());
            ejzh.setYe((ejzh.getYe()==null?0:ejzh.getYe())+sfk.getSfje());
            ejzhDao.save(ejzh);
        }
        this.fkshDao.save(sfk);
    }

    @Transactional
    public void FkshTh(Long id, String status) {
        Sfk sfk = this.findFkshDetail(id);
        sfk.setZt(status);
        sfk.setLastUpdated(new Date());
        this.fkshDao.save(sfk);
    }

    //提现
    @Transactional
    public void applyCash(Sfk fksh) {
        Ejzh e = ejzhDao.get(fksh.getDfejzh().getId());
        nullId(fksh);
        fksh.setDfejzh(e);
        fksh.setDateCreated(new Date());
        if(fksh.getBz() != null){
            Pattern p = Pattern.compile("\t|\r|\n");
            Matcher m = p.matcher(fksh.getBz());
            String bz = m.replaceAll("");
            fksh.setBz(bz);
        }
        fksh.setWlzlx(0);
        fksh.setSfklx(1);
        fksh.setKxlx(2);
        fksh.setCreateUser(YgService.getCurrentYg());
        fksh.setCreateOrgan(YgService.getCurrentYg().getZggs());
        fksh.setCreateDepartment(YgService.getCurrentYg().getZgjg());
        fksh.setLastUpdated(fksh.getDateCreated());
        fksh.setBm(this.bmService.getSfdbm("FK"));
        fksh.setSfwsyfk(0);
        fksh.setZt("ybc");
        fksh.setQtfk(0);
        this.fkshDao.save(fksh);
    }

    /**
     * 关联判断
     *
     * @param sfk
     */
    private void nullId(Sfk sfk) {
        if (sfk != null && sfk.getPjlx() != null && sfk.getPjlx().getId() == null)
            sfk.setPjlx(null);
        if (sfk != null && sfk.getGldw() != null && sfk.getGldw().getId() == null)
            sfk.setGldw(null);
        if (sfk != null && sfk.getHt() != null && sfk.getHt().getId() == null)
            sfk.setHt(null);
        if (sfk != null && sfk.getHklx() != null && sfk.getHklx().getId() == null)
            sfk.setHklx(null);
        if (sfk != null && sfk.getSbgs() != null && sfk.getSbgs().getId() == null)
            sfk.setSbgs(null);
        if (sfk != null && sfk.getSbbm() != null && sfk.getSbbm().getId() == null)
            sfk.setSbbm(null);
        if (sfk != null && sfk.getSbr() != null && sfk.getSbr().getId() == null)
            sfk.setSbr(null);
    }

    @Autowired
    public void setBmService(BmService bmService) {
        this.bmService = bmService;
    }

    @Autowired
    public void setFkshDao(FkshDao fkshDao) {
        this.fkshDao = fkshDao;
    }

    @Autowired
    public void setKhhService(KhhService khhService) {
        this.khhService = khhService;
    }

    @Autowired
    public void setPjglService(PjglService pjglService) {
        this.pjglService = pjglService;
    }

    @Autowired
    public void setJkdDao(JkdDao jkdDao) {
        this.jkdDao = jkdDao;
    }


    @Autowired
    public void setFkshmxDao(FkshmxDao fkshmxDao) {
        this.fkshmxDao = fkshmxDao;
    }

    @Autowired
    public void setJkdService(JkdService jkdService) {
        this.jkdService = jkdService;
    }

    @Autowired
    public void setXyzService(XyzService xyzService) {
        this.xyzService = xyzService;
    }

    @Autowired
    public void setGsjgDao(GsjgDao gsjgDao) {
        this.gsjgDao = gsjgDao;
    }

    @Autowired
    public void setFlowService(FlowService flowService) {
        this.flowService = flowService;
    }

    @Autowired
    public void setPjglDao(PjglDao pjglDao) {
        this.pjglDao = pjglDao;
    }

    @Autowired
    public void setXyzDao(XyzDao xyzDao) {
        this.xyzDao = xyzDao;
    }

    @Autowired
    public void setEjzhDao(EjzhDao ejzhDao) {
        this.ejzhDao = ejzhDao;
    }
    @Autowired
    public void setDxpzService(DxpzService dxpzService) {
        this.dxpzService = dxpzService;
    }
}
